package com.mvu.banana.common.server;

import com.mvu.banana.common.client.ServiceToken;
import com.mvu.banana.common.client.SystemConstants;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LoginServlet extends MyHttpServlet implements Filter, SystemConstants {

  private final Pattern PARAM_PATTERN = Pattern.compile(PAGE_ATTR + "=\\w*");

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServiceToken serviceToken = SessionManager.get().login(request);
    if (PermissionChecker.get().isAuthorized(request)) {
      // redirect to destination
      redirect(request, response, request.getParameter(TARGET_PARAM));
    } else {
      // forward back to source
      // caution: this will bypass filter
      forward(request, response, request.getParameter(SOURCE_PARAM));
    }
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    SessionManager.get().logout(request);
    redirect(request, response, GUEST);
  }

  protected void forward(HttpServletRequest request, HttpServletResponse response, String target) throws ServletException, IOException {
    ServletContext servletContext = getServletConfig().getServletContext();
    RequestDispatcher dispatcher = servletContext.getRequestDispatcher(HOST_PAGE);
    request.setAttribute(PAGE_ATTR, target);
    dispatcher.forward(request, response);
  }

  private void redirect(HttpServletRequest request, HttpServletResponse response, String destination) throws IOException {
    StringBuilder urlBuilder = new StringBuilder(request.getContextPath()).append(HOST_PAGE).append("?");
    String queryString = request.getQueryString();
    if (queryString == null) {
      urlBuilder.append(PAGE_ATTR).append("=").append(destination);
    } else {
      Matcher matcher = PARAM_PATTERN.matcher(queryString);
      if (matcher.matches()) {
        queryString = matcher.replaceFirst(PAGE_ATTR + "=" + destination);
        urlBuilder.append(queryString);
      } else {
        urlBuilder.append(queryString).append("&").append(PAGE_ATTR).append("=").append(destination);
      }
    }
    response.sendRedirect(urlBuilder.toString());
  }

  public void init(FilterConfig filterConfig) throws ServletException {
  }

  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String page = request.getParameter(PAGE_ATTR);
    if (page != null) {
      request.setAttribute(PAGE_ATTR, page);
    } else if (request.getAttribute(PAGE_ATTR) == null || !PermissionChecker.get().isAuthorized(request)) {
      request.setAttribute(PAGE_ATTR, GUEST);
    }
    filterChain.doFilter(servletRequest, servletResponse);
  }
}
